package club.vann.leetcode.race;

import sun.jvm.hotspot.opto.HaltNode;

import java.util.HashMap;
import java.util.Map;

/**
 * <p>难度：Easy</p>
 * <p>题目：仅执行一次字符串交换能否使两个字符串相等</p>
 * <p>描述：给你长度相等的两个字符串 s1 和 s2 。一次 字符串交换 操作的步骤如下：选出某个字符串中的两个下标（不必不同），并交换这两个下标所对应的字符。
 *
 * 如果对 其中一个字符串 执行 最多一次字符串交换 就可以使两个字符串相等，返回 true ；否则，返回 false 。
 *
 *
 *
 * 示例 1：
 *
 * 输入：s1 = "bank", s2 = "kanb"
 * 输出：true
 * 解释：例如，交换 s2 中的第一个和最后一个字符可以得到 "bank"
 * 示例 2：
 *
 * 输入：s1 = "attack", s2 = "defend"
 * 输出：false
 * 解释：一次字符串交换无法使两个字符串相等
 * 示例 3：
 *
 * 输入：s1 = "kelb", s2 = "kelb"
 * 输出：true
 * 解释：两个字符串已经相等，所以不需要进行字符串交换
 * 示例 4：
 *
 * 输入：s1 = "abcd", s2 = "dcba"
 * 输出：false
 *
 *
 * 提示：
 *
 * 1 <= s1.length, s2.length <= 100
 * s1.length == s2.length
 * s1 和 s2 仅由小写英文字母组成</p>
 * @author vann
 * @program now-coder
 * @description
 * @date 2021-03-14:10:39:03
 */
public class LeetCode_5701 {
    public static void main(String[] args) {
        LeetCode_5701 leetCode = new LeetCode_5701();

        System.out.println("Result["+TestCase.ANS+"] : " + leetCode.areAlmostEqual(TestCase.STRS[0], TestCase.STRS[1]));
        System.out.println("Result["+TestCase.ANS1+"] : " + leetCode.areAlmostEqual(TestCase.STRS1[0], TestCase.STRS1[1]));
        System.out.println("Result["+TestCase.ANS2+"] : " + leetCode.areAlmostEqual(TestCase.STRS2[0], TestCase.STRS2[1]));
        System.out.println("Result["+TestCase.ANS3+"] : " + leetCode.areAlmostEqual(TestCase.STRS3[0], TestCase.STRS3[1]));
        System.out.println("Result["+TestCase.ANS4+"] : " + leetCode.areAlmostEqual(TestCase.STRS4[0], TestCase.STRS4[1]));
        System.out.println("Result["+TestCase.ANS5+"] : " + leetCode.areAlmostEqual(TestCase.STRS5[0], TestCase.STRS5[1]));
    }

    /**
     * 解法一：
     *
     * @param s1
     * @param s2
     * @return
     */
    public boolean areAlmostEqual(String s1, String s2) {
        if(s1.equals(s2)) {
            return true;
        }

        char[] ch1 = s1.toCharArray();
        char[] ch2 = s2.toCharArray();
        Map<Character, Integer> map = new HashMap<>();
        for(char c : ch2) {
            map.put(c, map.getOrDefault(c, 0) + 1);
        }
        int len = ch1.length;
        int diff = 0;
        for(int i = 0; i < len; i ++) {
            char c = ch1[i];
            if(!map.containsKey(c)) {
                return false;
            }

            if(ch1[i] != ch2[i]) {
                diff ++;
            }

            int count = map.get(c);
            count --;
            if(count == 0) {
                map.remove(c);
            } else {
                map.put(c, count);
            }

            if(diff > 2) {
                return false;
            }
        }
        return true;
    }

    static class TestCase {
        public static boolean ANS = true;
        public static String[] STRS = {"bank", "kanb"};

        public static boolean ANS1 = false;
        public static String[] STRS1 = {"attack", "defend"};

        public static boolean ANS2 = true;
        public static String[] STRS2 = {"kelb", "kelb"};

        public static boolean ANS3 = false;
        public static String[] STRS3 = {"abcd", "dcba"};

        public static boolean ANS4 = false;
        public static String[] STRS4 = {"abcdefg", "gcbdefa"};

        public static boolean ANS5 = false;
        public static String[] STRS5 = {"aaaa", "aabb"};
    }
}
